Points


Since data variables are typically mapped to either nodes, edges, or faces, one can visualize these by using the data to shade the coordinate points of each element.

Setup

Imports

import cartopy.crs as ccrs
import geoviews.feature as gf
import uxarray as ux
from holoviews import opts

file_dir = "../../meshfiles/"
/home/runner/miniconda3/envs/cookbook-dev/lib/python3.10/site-packages/dask/dataframe/_pyarrow_compat.py:17: FutureWarning: Minimal version of pyarrow will soon be increased to 14.0.1. You are using 12.0.1. Please consider upgrading.
  warnings.warn(

Datasets

grid_filename_120 = file_dir + "oQU120.grid.nc"
data_filename_120 = file_dir + "oQU120.data.nc"
uxds_120km = ux.open_dataset(grid_filename_120, data_filename_120)
grid_filename_480 = file_dir + "oQU480.grid.nc"
data_filename_480 = file_dir + "oQU480.data.nc"
uxds_480km = ux.open_dataset(grid_filename_480, data_filename_480)

Vector Point Plots

We can plot each shaded data point using the latitude and longitude of either the nodes, edge centers, or face centers. Since “bottomDepth” is a face-centered variable, it is plotted with the node coordinates.

uxds_480km["bottomDepth"].plot.points(width=900, height=400)
uxds_480km["bottomDepth"].plot.points(
    projection=ccrs.Orthographic(), width=500, height=500, size=5
)

Rasterized Point Plots

Instead of plotting each point, we can rasterize our set of points.

(
    uxds_480km["bottomDepth"].plot.rasterize(
        method="point", width=900, height=400, title="480km Grid"
    )
    + uxds_120km["bottomDepth"].plot.rasterize(
        method="point", width=900, height=400, title="120km Grid"
    )
).cols(1)

As the resolution of our grid increases, we can observe that there is a much higher density of points, and you can start to vaguely see the outline of the data variables.

By selecting a pixel_ratio parameter, you can control the size of the “pixels” or “bins” used for rasterization. A smaller pixel ratio increases the size of the bins used for rasterization, while a larger pixel ratio makes the bins smaller.

For our case, we want to select a small pixel ratio to group points into “structured” bins.

uxds_120km["bottomDepth"].plot.rasterize(
    method="point", pixel_ratio=0.40, width=900, height=400
)

This result looks much better than just plotting points. However, without a projection, the density of points near the poles is significantly lower, which means that some bins do not contain any data points.

We can get a better result by chosing a projection that more evenly distributes the points.

uxds_120km["bottomDepth"].plot.rasterize(
    method="point",
    projection=ccrs.Sinusoidal(),
    width=900,
    height=400,
    pixel_ratio=0.4,
)

High-Resolution Example

The grids used in this notebook so far have had resolutions of 480km and 120km. These resolutions are not sufficient for reaching high levels of data fidelity in the resulting point rasters.

The following screenshots were rendered using a 3.75km mesh.

global plot

Since point rasterization is heavily dependent on the density of points, we can see that without a projection, both poles have large quanities of missing values

This can be avoided by choosing a projection that better distributes the points.

global plot